/**
 * Created by jiangqifan on 2017/6/20.
 */
(function() {
    ADF.actionModel.PasteModel = function() {
        ADF.actionModel.PasteModel.superclass.constructor.call(this);
        this.config = {text:"粘贴",icon:"icon-niantie"};
        this.id = "paste";
    };

    /**
     * 判断editpart是否为容器
     *
     */
    function isComposite(editPart){
      return COM.util.isInstanceOf(editPart, ADF.editpart.DiagramEditPart) ||
             COM.util.isInstanceOf(editPart.model,ADF.model.CompositeModel);
    }

    /**
     * 判断两个模型数组中是否有相同的id
     */
    function hasDuplicateId(models, otherModels){
      var idMap = {};
      var hasDuplicate = false;

      for(var i = 0; i < models.length; i++){
        var model = models[i];
        var id = model.id;
        idMap[id] = true;
      }

      for(var i = 0; i < otherModels.length; i++){
        var model = otherModels[i];
        var id = model.id;
        if(idMap[id]){
          hasDuplicate = true;
          break;
        } else {
          idMap[id] = true;
        }
      }
      return hasDuplicate;
    }

    /**
     * 计算父editpart
     * @param selections 当前选中项
     * @param newModels 需要粘贴的模型
     */
    function calculateParent(selections, newModels){
      var firstSelection = selections[0];
      //如果当前选中Diagram，就复制到Diagram中
      if(COM.util.isInstanceOf(firstSelection, ADF.editpart.DiagramEditPart)){
        return firstSelection;
      }

      //如果是容器，且选中的容器不在剪切版，则复制到此容器中
      if(isComposite(firstSelection)){
        if(!hasDuplicateId(newModels, [firstSelection.model])){
          return firstSelection;
        }
      }

      //如果当前选中中跟要粘贴的内容有相同id，就复制到选中项的父中
      var parent = firstSelection.parent;
      var children = parent.model.getPropertyValue("children");
      if(hasDuplicateId(newModels, children)){
        return parent;
      }

      //如果当前选中是容器，就复制到当前选中项中
      if(isComposite(firstSelection)){
        return firstSelection;
      } else {
        return parent;
      }
    }

    COM.util.defineClass(ADF.actionModel.PasteModel, AGEF.ActionModel, {
        execute: function(graphicalViewer){
            try{
              var clipboardString = this.getCopyModels();
              var selections = graphicalViewer.getSelection();

              if(clipboardString != this.lastPasteContent){
                this.lastPasteContent = clipboardString;
                this.pasteCount = {};
              }

              var outter = this;

              function countPaste(key){
                if(!outter.pasteCount){
                  outter.pasteCount = {};
                  outter.pasteCount[key] = 1;
                }
                if(outter.pasteCount[key]){
                  outter.pasteCount[key]++;
                } else {
                  outter.pasteCount[key] = 1;
                }
              }

              function deCountPaste(key){
                if(!outter.pasteCount){
                }
                if(outter.pasteCount[key]>1){
                  outter.pasteCount[key]--;
                } else {
                  outter.pasteCount[key] = 0;
                }
              }

              function getPasteCount(key){
                if(outter.pasteCount && outter.pasteCount[key]){
                  return outter.pasteCount[key];
                }
                return 0;
              }

              function deserialize(clipboardString, offset){
                var modelStrings = JSON.parse(clipboardString);
                var modelObjecs = [];
                for(var i = 0; i < modelStrings.length; i++){
                  var modelString = modelStrings[i];
                  var model = JSON.parse(modelString);
                  var modelType = model["modelType"], modelConstructor = eval("("+modelType+")");
                  var contentModel = new modelConstructor();
                  contentModel.deserialize(JSON.stringify(model));


                  modelObjecs.push(contentModel);
                }
                return modelObjecs;
              }

              function addOffset(models, offset){
                for(var i = 0; i < models.length; i++ ){
                  var contentModel = models[i];
                  var oldValue = contentModel.getPropertyValue("layoutdata");
                  if(oldValue && oldValue.x !== null && oldValue.x != undefined && oldValue.y != undefined && oldValue.y != undefined ){
                      var newValue = new COM.draw2d.Rectangle();
                      newValue.x = oldValue.x + offset;
                      newValue.y = oldValue.y + offset;
                      newValue.width = oldValue.width;
                      newValue.height = oldValue.height;
                      contentModel.setPropertyValue("layoutdata",newValue);
                  }
                }
              }

              var models = deserialize(clipboardString);
              var parent = calculateParent(selections, models);
              addOffset(models,(getPasteCount(parent.model.id)+1) * 10);

              var cmd = COM.gef.Command.createCommand({
                  models: models,
                  parent: parent,
                  findParentModel: function(){
                    return this.parent.model;
                  },
                  execute: function() {
                    var models = this.models;
                    var parent = this.findParentModel();
                    countPaste(parent.id);
                    var idMap = {};
                    for(var i = 0; i < this.models.length; i++){
                      var id = COM.util.ObjUtil.generateID();
                      idMap[id] = true;
                      models[i].id = id;
                      parent.addChild(models[i]);
                    }

                    //选中新增的model
                    var children = this.parent.children;
                    var toSelectChildren = [];
                    for(var i = 0; i < children.length; i++){
                      if(idMap[children[i].model.id]){
                        toSelectChildren.push(children[i]);
                      }
                    }
                    graphicalViewer.setSelection(toSelectChildren);

                  },

                  undo: function() {
                    var models = this.models;
                    var parent = this.findParentModel();
                    var children = parent.getPropertyValue(ADF.model.DiagramModel.PROPERTY_CHILDREN);
                    var newChildren = children.slice(0, children.length);
                    for(var i=0; i < models.length; i++){
                      newChildren.pop();
                    }

                    deCountPaste(parent.id);
                    parent.setPropertyValue(ADF.model.DiagramModel.PROPERTY_CHILDREN, newChildren);
                  }
              });

              var domain = graphicalViewer.getEditDomain();
              var stack = domain.getCommandStack();
              stack.execute(cmd);

            } catch(e){
              console.debug('粘贴失败');
              return;
            }
        },
        getCopyModels: function(){
          var prefix = "adfmodels:"
          if(ADF.actionModel.CopyModel.clipboard
            && ADF.actionModel.CopyModel.clipboard.substr
            && prefix == ADF.actionModel.CopyModel.clipboard.substr(0,10)){
              return ADF.actionModel.CopyModel.clipboard.substr(10);
          } else {
            return null;
          }

        },
        getEnabledState: function(graphicalViewer){
          if(!this.getCopyModels()){
            return false;
          }
          return true;
        }

    });
})();
